package com.example.jimuyutabletcontrol.activity;

import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Display;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.example.jimuyutabletcontrol.R;
import com.example.jimuyutabletcontrol.adapter.fileadapter.SelectAUVAnalyseAdapter;
import com.example.jimuyutabletcontrol.adapter.selectauvrecord.SelectAUVRecordAdapter;
import com.example.jimuyutabletcontrol.network.udp.UdpMessageHandle;
import com.example.jimuyutabletcontrol.network.udp.UdpMessageType;
import com.example.jimuyutabletcontrol.network.udp.UdpSocket;
import com.example.jimuyutabletcontrol.utils.Tools;
import com.orhanobut.dialogplus.DialogPlus;
import com.scwang.smartrefresh.layout.SmartRefreshLayout;
import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.scwang.smartrefresh.layout.listener.OnRefreshLoadmoreListener;

import java.util.ArrayList;
import java.util.List;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.RecyclerView;

public class SelectAUVAnalyseActivity extends AppCompatActivity implements
        Toolbar.OnMenuItemClickListener, View.OnClickListener, OnRefreshLoadmoreListener {
    private UdpMessageHandle handle;

    private Point[] pentagonVertices;
    private Button[] buttons;
    private int width;
    private int radius;
    private int startPositionX;
    private int startPositionY;
    private int whichAnimation;
    private int NUM_OF_SIDES;
    private int[] enterDelay = {80, 120, 160, 40, 0, 200, 240};
    private int[] exitDelay = {80, 40, 0, 120, 160, 200, 240};
    private String[] content = {"获取数据"};

    private Toolbar toolbar;

    private SmartRefreshLayout mSmartRefreshLayout;

    private RecyclerView mRecyclerView;

    private TextView noData;

    private SelectAUVRecordAdapter adapter;

    /**
     * ==0,下拉刷新；==1，上拉加载
     */
    private int loadType = 0;

    private List<String> infos;

    protected void onDestroy() {
        super.onDestroy();
        if (null != handle) {
            UdpSocket.getInstance().removeMessageCallback(handle);
            handle = null;
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.selectauvanalyseinterface_pull_to_refresh);
        initView();
        setAdapter();
        setListeners();
        mSmartRefreshLayout.autoRefresh();
        prepareFloatButton();
    }

    private void setAdapter() {
        infos = new ArrayList<>();
        adapter = new SelectAUVRecordAdapter(infos);
        mRecyclerView.setAdapter(adapter);
    }

    private void initView() {
        toolbar = findViewById(R.id.toolbaranalyse);
        toolbar.setTitle("AUV数据分析");
        setSupportActionBar(toolbar);
        mSmartRefreshLayout = findViewById(R.id.mSmartRefreshLayout);
        mRecyclerView = findViewById(R.id.mRecyclerView);
        noData = findViewById(R.id.noData);
    }

    private void setListeners() {
        if (toolbar != null) {
            toolbar.setOnMenuItemClickListener(this);
        }
        adapter.setOnSelectAUVRecordListener(position -> showDialogWithData(infos.get(position)));
        handle = new UdpMessageHandle(UdpMessageType.IMEI, msg -> {
            if (loadType == 0) {
                mSmartRefreshLayout.finishRefresh(true);
            } else {
                mSmartRefreshLayout.finishLoadmore(true);
            }
            updateListData(msg);
        });
        UdpSocket.getInstance().setMessageCallback(handle);
        mSmartRefreshLayout.setOnRefreshLoadmoreListener(this);
    }


    @Override
    public void onClick(View view) {
        Intent intent = null;
        switch ((int) view.getTag()) {
            case 0:
                intent = new Intent(SelectAUVAnalyseActivity.this, SelectAUVRecordDataActivity.class);
                startActivity(intent);
                break;
        }
    }

    @Override
    public void onLoadmore(RefreshLayout refreshlayout) {
        UdpSocket.getInstance().sendMessage("INSTANTIMEI");
        loadType = 1;
    }

    @Override
    public void onRefresh(RefreshLayout refreshlayout) {
        UdpSocket.getInstance().sendMessage("INSTANTIMEI");
        loadType = 0;
    }

    private void showDialogWithData(String s) {
        ArrayList<String> files = Tools.getAllFileName();
        if (files == null) {
            return;
        }
        final List<String> tmpList = new ArrayList<>();
        final List<Long> containerList = new ArrayList<>();
        for (String file : files) {
            if (file.contains(s)) {
                tmpList.add(file);
                containerList.add(Tools.getSecondTime(file));
            }
        }
        final List<String> list = Tools.getOrderList(tmpList, containerList);
        SelectAUVAnalyseAdapter simpleAdapter = new SelectAUVAnalyseAdapter(this, list);
        DialogPlus.newDialog(this)
                .setAdapter(simpleAdapter)
                .setOnItemClickListener(((dialogPlus, item, view, position) -> showSelectDialog(list.get(position),dialogPlus)))
                .setExpanded(true)  // This will enable the expand feature, (similar to android L share dialog)
                .create()
                .show();
    }

    private void showSelectDialog(String fileName ,DialogPlus dialogPlus) {
        new AlertDialog.Builder(SelectAUVAnalyseActivity.this)
                .setTitle("选择文件：" + fileName + " 要分析的数据类型")
                .setNegativeButton("GPS", ((dialog, which) -> {
                    Intent intent = null;
                    if (fileName.contains("DS")) {
                        intent = new Intent(SelectAUVAnalyseActivity.this, AnalysingGPSDSActivity.class);
                    } else {
                        intent = new Intent(SelectAUVAnalyseActivity.this, AnalysingGPSDHActivity.class);
                    }
                    intent.putExtra("fileName", fileName);
                    startActivity(intent);
                    dialogPlus.dismiss();
                    dialog.dismiss();
                }))
                .setPositiveButton("Sensor", ((dialog, which) -> {
                    Intent intent = null;
                    if (fileName.contains("DS")) {
                        intent = new Intent(SelectAUVAnalyseActivity.this, AnalysingSensorDSActivity.class);
                    } else {
                        intent = new Intent(SelectAUVAnalyseActivity.this, AnalysingSensorDHActivity.class);
                    }
                    intent.putExtra("fileName", fileName);
                    startActivity(intent);
                    dialogPlus.dismiss();
                    dialog.dismiss();
                })).create()
                .show();
    }

    private void updateListData(String message) {
        runOnUiThread(() -> {
            String[] contents = message.split(",");
            List<String> strs = new ArrayList<>();
            for (int i = 1; i < contents.length; i++) {
                if (!infos.contains(contents[i])) {
                    strs.add(contents[i]);
                }
            }
            if (strs.size() > 0) {
                int refreshindex = infos.size();
                infos.addAll(strs);
                adapter.notifyItemRangeInserted(refreshindex, strs.size());
            }
            noData.setVisibility((null == infos || infos.size() == 0) ? View.VISIBLE : View.GONE);
        });
    }

    private void toastMsg(final String msg) {
        runOnUiThread(() -> Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show());
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.selectauvanalyseinterface_menu, menu);
        return true;
    }

    @Override
    public boolean onMenuItemClick(MenuItem menuItem) {
        if (menuItem.getItemId() == R.id.auvanalyse_clear) {
            infos.clear();
            adapter.notifyDataSetChanged();
            mSmartRefreshLayout.autoRefresh();
        } else if (menuItem.getItemId() == R.id.send_analyse) {
            if (whichAnimation == 0) {
                /**
                 * Getting the center point of floating action button
                 *  to set start point of buttons
                 */
                startPositionX = 2600;
                startPositionY = 0;
                for (Button button : buttons) {
                    button.setX(startPositionX);
                    button.setY(startPositionY);
                    button.setVisibility(View.VISIBLE);
                }
                for (int i = 0; i < buttons.length; i++) {
                    playEnterAnimation(buttons[i], i);
                }
                whichAnimation = 1;
            } else {
                for (int i = 0; i < buttons.length; i++) {
                    playExitAnimation(buttons[i], i);
                }
                whichAnimation = 0;
            }
            return true;
        }
        return false;
    }

    private void prepareFloatButton() {
        startPositionX = 0;
        startPositionY = 0;
        whichAnimation = 0;
        NUM_OF_SIDES = 1;
        width = 200;
        radius = 200;
        calculatePentagonVertices(radius, 11);
    }

    private void calculatePentagonVertices(int radius, int rotation) {

        pentagonVertices = new Point[NUM_OF_SIDES];

        /**
         * Calculating the center of pentagon
         */
        Display display = getWindowManager().getDefaultDisplay();
        int centerX = display.getWidth() / 2;
        int centerY = display.getHeight() / 2;

        /**
         * Calculating the coordinates of vertices of pentagon
         */
        for (int i = 0; i < NUM_OF_SIDES; i++) {
            pentagonVertices[i] = new Point((int) (radius * Math.cos(rotation + i * 2 * Math.PI / NUM_OF_SIDES)) + centerX,
                    (int) (radius * Math.sin(rotation + i * 2 * Math.PI / NUM_OF_SIDES)) + centerY - 100);
        }

        buttons = new Button[pentagonVertices.length];

        for (int i = 0; i < buttons.length; i++) {
            //Adding button at (0,0) coordinates and setting their visibility to zero
            buttons[i] = new Button(SelectAUVAnalyseActivity.this);
            buttons[i].setLayoutParams(new RelativeLayout.LayoutParams(100, 100));
            buttons[i].setX(0);
            buttons[i].setY(0);
            buttons[i].setTag(i);
            buttons[i].setOnClickListener(this);
            buttons[i].setVisibility(View.INVISIBLE);
            buttons[i].setBackgroundResource(R.drawable.circular_background);
            buttons[i].setTextColor(Color.DKGRAY);
            buttons[i].setText(content[i]);
            buttons[i].setTextSize(14);
            /**
             * Adding those buttons in acitvities layout
             */
            ((LinearLayout) findViewById(R.id.main_analyse)).addView(buttons[i]);
        }
    }

    private void playEnterAnimation(final Button button, int position) {

        /**
         * Animator that animates buttons x and y position simultaneously with size
         */
        AnimatorSet buttonAnimator = new AnimatorSet();

        /**
         * ValueAnimator to update x position of a button
         */
        ValueAnimator buttonAnimatorX = ValueAnimator.ofFloat(startPositionX + button.getLayoutParams().width / 2,
                pentagonVertices[position].x);
        buttonAnimatorX.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                button.setX((float) animation.getAnimatedValue() - button.getLayoutParams().width / 2);
                button.requestLayout();
            }
        });
        buttonAnimatorX.setDuration(300);

        /**
         * ValueAnimator to update y position of a button
         */
        ValueAnimator buttonAnimatorY = ValueAnimator.ofFloat(startPositionY + 5,
                pentagonVertices[position].y);
        buttonAnimatorY.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                button.setY((float) animation.getAnimatedValue());
                button.requestLayout();
            }
        });
        buttonAnimatorY.setDuration(300);

        /**
         * This will increase the size of button
         */
        ValueAnimator buttonSizeAnimator = ValueAnimator.ofInt(5, width);
        buttonSizeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                button.getLayoutParams().width = (int) animation.getAnimatedValue();
                button.getLayoutParams().height = (int) animation.getAnimatedValue();
                button.requestLayout();
            }
        });
        buttonSizeAnimator.setDuration(300);

        /**
         * Add both x and y position update animation in
         *  animator set
         */
        buttonAnimator.play(buttonAnimatorX).with(buttonAnimatorY).with(buttonSizeAnimator);
        buttonAnimator.setStartDelay(enterDelay[position]);
        buttonAnimator.start();
    }

    private void playExitAnimation(final Button button, int position) {

        /**
         * Animator that animates buttons x and y position simultaneously with size
         */
        AnimatorSet buttonAnimator = new AnimatorSet();

        /**
         * ValueAnimator to update x position of a button
         */
        ValueAnimator buttonAnimatorX = ValueAnimator.ofFloat(pentagonVertices[position].x - button.getLayoutParams().width / 2,
                startPositionX);
        buttonAnimatorX.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                button.setX((float) animation.getAnimatedValue());
                button.requestLayout();
            }
        });
        buttonAnimatorX.setDuration(300);

        /**
         * ValueAnimator to update y position of a button
         */
        ValueAnimator buttonAnimatorY = ValueAnimator.ofFloat(pentagonVertices[position].y,
                startPositionY + 5);
        buttonAnimatorY.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                button.setY((float) animation.getAnimatedValue());
                button.requestLayout();
            }
        });
        buttonAnimatorY.setDuration(300);
        /**
         * This will decrease the size of button
         */
        ValueAnimator buttonSizeAnimator = ValueAnimator.ofInt(width, 5);
        buttonSizeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                button.getLayoutParams().width = (int) animation.getAnimatedValue();
                button.getLayoutParams().height = (int) animation.getAnimatedValue();
                button.requestLayout();
            }
        });
        buttonSizeAnimator.setDuration(300);

        /**
         * Add both x and y position update animation in
         *  animator set
         */
        buttonAnimator.play(buttonAnimatorX).with(buttonAnimatorY).with(buttonSizeAnimator);
        buttonAnimator.setStartDelay(exitDelay[position]);
        buttonAnimator.start();
    }

}
